package com.wg.core.io;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.util.List;

/**
 * 二进制数据读取接口
 *
 * <p>
 * 提供大端序(big-endian)格式的二进制数据读取能力，
 * 支持基本类型、字符串、数组、集合和自定义可序列化对象的读取操作。
 * </p>
 *
 * @author 少爷123
 */
public interface IBinaryReader {

    // ===================== 布尔类型 =====================

    /**
     * 读取布尔值
     *
     * @return 读取的布尔值
     */
    boolean readBoolean();

    /**
     * 读取布尔值数组
     *
     * @return 布尔值数组
     */
    boolean[] readBooleanArray();

    /**
     * 读取布尔值集合
     *
     * @return 布尔值集合
     */
    List<Boolean> readBooleanCollection();

    // ===================== 字节类型 =====================

    /**
     * 读取单个字节
     *
     * @return 读取的字节值
     */
    byte readByte();

    /**
     * 读取指定长度的原始字节数组
     *
     * @param length 要读取的字节长度
     * @return 字节数组
     */
    byte[] readBytes(int length);

    /**
     * 读取带长度信息的字节数组
     *
     * @return 字节数组（包含长度前缀）
     */
    byte[] readBytesWithLength();

    /**
     * 读取剩余所有字节
     *
     * @return 剩余字节数组
     */
    byte[] readRemainingBytes();

    // ===================== 字符类型 =====================

    /**
     * 读取字符
     *
     * @return 读取的字符值
     */
    char readChar();

    /**
     * 读取字符数组
     *
     * @return 字符数组
     */
    char[] readCharArray();

    // ===================== 双精度浮点 =====================

    /**
     * 读取双精度浮点数
     *
     * @return 双精度浮点值
     */
    double readDouble();

    /**
     * 读取双精度浮点数组
     *
     * @return 双精度浮点数组
     */
    double[] readDoubleArray();

    /**
     * 读取双精度浮点集合
     *
     * @return 双精度浮点集合
     */
    List<Double> readDoubleCollection();

    // ===================== 短整型 =====================

    /**
     * 读取短整型数值
     *
     * @return 短整型值
     */
    short readShort();

    /**
     * 读取短整型数组
     *
     * @return 短整型数组
     */
    short[] readShortArray();

    /**
     * 读取短整型集合
     *
     * @return 短整型集合
     */
    List<Short> readShortCollection();

    // ===================== 整型 =====================

    /**
     * 读取整型数值
     *
     * @return 整型值
     */
    int readInt();

    /**
     * 读取整型数组
     *
     * @return 整型数组
     */
    int[] readIntArray();

    /**
     * 读取整型集合
     *
     * @return 整型集合
     */
    List<Integer> readIntCollection();

    /**
     * 读取大整数(BigInteger)值
     *
     * @return 大整数值
     */
    BigInteger readBigInteger();

    // ===================== 长整型 =====================

    /**
     * 读取长整型数值
     *
     * @return 长整型值
     */
    long readLong();

    /**
     * 读取长整型数组
     *
     * @return 长整型数组
     */
    long[] readLongArray();

    /**
     * 读取长整型集合
     *
     * @return 长整型集合
     */
    List<Long> readLongCollection();

    // ===================== 单精度浮点 =====================

    /**
     * 读取单精度浮点数
     *
     * @return 单精度浮点值
     */
    float readFloat();

    /**
     * 读取单精度浮点数组
     *
     * @return 单精度浮点数组
     */
    float[] readFloatArray();

    /**
     * 读取单精度浮点集合
     *
     * @return 单精度浮点集合
     */
    List<Float> readFloatCollection();

    // ===================== 字符串 =====================

    /**
     * 读取字符串（支持长字符串特殊处理）
     *
     * @return 字符串值
     */
    String readString();

    /**
     * 读取字符串数组
     *
     * @return 字符串数组
     */
    String[] readStringArray();

    /**
     * 读取字符串集合
     *
     * @return 字符串集合
     */
    List<String> readStringCollection();

    // ===================== 可序列化对象 =====================

    /**
     * 读取可序列化对象
     *
     * @param <T>   实现ISerializerRead接口的类型
     * @param clazz 对象类型
     * @return 可序列化对象实例
     */
    <T extends IBinaryReadable> T readObject(Class<T> clazz);

    /**
     * 读取可序列化对象数组
     *
     * @param <T>   实现ISerializerRead接口的类型
     * @param clazz 对象类型
     * @return 可序列化对象数组
     */
    <T extends IBinaryReadable> T[] readObjectArray(Class<T> clazz);

    /**
     * 读取可序列化对象集合
     *
     * @param <T>   实现ISerializerRead接口的类型
     * @param clazz 对象类型
     * @return 可序列化对象集合
     */
    <T extends IBinaryReadable> List<T> readObjectCollection(Class<T> clazz);

    // ===================== 流操作 =====================

    /**
     * 获取底层字节输入流
     *
     * @return 底层字节输入流
     */
    ByteArrayInputStream baseStream();
}